//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifdef __UX_STL_UNIT_TEST__

#include "../ux_stl_core.h"

using namespace UX_STL;
using namespace UXTypes;


struct Test1
{
	typedef delegate< void () >		delegate_t;
	typedef function< void >		function_t;
	typedef event< delegate_t >		event_t;

	static void Func ()
	{
		DEBUG_CONSOLE( UX_FUNCTION_NAME );
	}

	static void Test ()
	{
		delegate_t	d;		DelegateBuilder::Create( d, Func );
		function_t	f;		FunctionBuilder::Create( f, Func );
		event_t		e;

		e.Add( d );
		e.Add( d );
		e.Call();

		d.Call();
		f.Call();
	}
};

struct Test2
{
	typedef delegate< void (int) >		delegate_t;
	typedef function< void >			function_t;
	typedef event< delegate_t >			event_t;

	static void Func (int i)
	{
		DEBUG_CONSOLE( (string(UX_FUNCTION_NAME) << " " << i).cstr() );
	}

	static void Test ()
	{
		delegate_t	d;		DelegateBuilder::Create( d, Func );
		function_t	f;		FunctionBuilder::Create( f, Func, 2 );
		event_t		e;

		e.Add( d );
		e.Add( d );
		e.Call( 3 );

		d.Call( 1 );
		f.Call();

		d.SafeCall( 4 );
	}
};

struct Test3
{
	typedef delegate< void () >		delegate_t;
	typedef function< void >		function_t;
	typedef event< delegate_t >		event_t;

	void Func ()
	{
		DEBUG_CONSOLE( UX_FUNCTION_NAME );
	}

	static void Test ()
	{
		Test3 t;
		delegate_t	d;		DelegateBuilder::Create( d, &t, &Test3::Func );
		function_t	f;		FunctionBuilder::Create( f, &t, &Test3::Func );
		event_t		e;

		e.Add( d );
		e.Add( d );
		e.Call();

		d.Call();
		f.Call();
	}
};

struct Test4
{
	typedef delegate< void (const float &) >	delegate_t;
	typedef function< void >					function_t;
	typedef event< delegate_t >					event_t;

	void Func (const float &f) const
	{
		DEBUG_CONSOLE( (string(UX_FUNCTION_NAME) << " " << f).cstr() );
	}

	static void Test ()
	{
		Test4 t;
		delegate_t	d;		DelegateBuilder::Create( d, &t, &Test4::Func );
		function_t	f;		FunctionBuilder::Type< void (Test4:: *) (const float &) const >::Create( f, &t, &Test4::Func, 2.0f );
		function_t	f1;		FunctionBuilder::Create( f1, &t, &Test4::Func, 4.0f );
		event_t		e;

		e.Add( d );
		e.Add( d );
		e.Call( 3.0f );

		d.Call( 1.0f );
		f.Call();
		f1.Call();
	}
};


class Test5 : public CReferenced
{
public:
	typedef delegate< void (int, int) >		delegate_t;
	typedef function< void >				function_t;
	typedef event< delegate_t >				event_t;

	SHARED_POINTER( Test5 );

	~Test5 () { DEBUG_CONSOLE( UX_FUNCTION_NAME ); }

	void Func (int a, int b) const
	{
		DEBUG_CONSOLE( (string(UX_FUNCTION_NAME) << " " << a << ", " << b).cstr() );
	}

	static void Test ()
	{
		delegate_t	d;
		function_t	f;
		event_t		e;

		{
			Test5Ptr t = new Test5();

			DelegateBuilder::Create( d, t, &Test5::Func );
			FunctionBuilder::Create( f, t, &Test5::Func, 1, 2 );
			
			e.Add( d );
			e.Add( d );
		}

		e.Call( 3, 4 );

		d.Call( 5, 6 );
		f.Call();
	}
};


void Test_Types_Function ()
{
	Test1::Test();
	Test2::Test();
	Test3::Test();
	Test4::Test();
	Test5::Test();
}


#endif	// __UX_STL_UNIT_TEST__